package com.tengfei.blogsystem.controller.user;

import com.tengfei.blogsystem.pojo.User;
import com.tengfei.blogsystem.response.ResponseResult;
import com.tengfei.blogsystem.response.ResponseState;
import com.tengfei.blogsystem.service.IUserService;
import com.tengfei.blogsystem.service.impl.TaskServiceImpl;
import com.tengfei.blogsystem.utils.Constants;
import com.tengfei.blogsystem.utils.RedisUtil;
import com.tengfei.blogsystem.utils.TextUtils;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.util.Random;

/**
 * @version v1.0
 * @author} feige
 * @date 2021-10-14-19:50
 * @description
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserApi {

    @Autowired
    IUserService userService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    TaskServiceImpl taskService;


    /**
     * 初始化管理员账号
     *
     * @param user
     * @param request
     * @reutrn
     */
    @PostMapping("/admin_account")
    public ResponseResult initManagerAccount(@RequestBody User user, HttpServletRequest request) {
        return userService.initManagerAccount(user, request);
    }

    /**
     * 用户注册
     *
     * @param user
     * @param emailCode
     * @param checkCode
     * @param checkKey
     * @reutrn
     */
    @PostMapping("/register/{emailCode}/{checkCode}/{checkKey}")
    public ResponseResult register(@RequestBody User user, @PathVariable("emailCode") String emailCode,
                                   @PathVariable("checkCode") String checkCode,
                                   @PathVariable("checkKey") String checkKey, HttpServletRequest request) {
        return userService.register(user, emailCode, checkCode, checkKey, request);
    }

    /**
     * 用户登录
     *
     * @param captcha
     * @param captchaKey
     * @param user
     * @reutrn
     */
    @PostMapping("/login/{captcha}/{captchaKey}")
    public ResponseResult login(@PathVariable("captcha") String captcha,
                                @PathVariable("captchaKey") String captchaKey,
                                @RequestBody User user,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        return userService.doLogin(captcha, captchaKey, user, request, response);
    }

    /**
     * 获取验证码
     *
     * @reutrn void
     */
    @GetMapping("/captcha/{captchaKey}")
    public void captcha(HttpServletResponse response, @PathVariable("captchaKey") String captchaKey) throws Exception {
        if (TextUtils.isEmpty(captchaKey) || captchaKey.length() < 13) {
            return;
        }
        long key = 01;
        try {
            key = Long.parseLong(captchaKey);
        } catch (Exception e) {
            return;
        }
        // 设置请求头
        response.setContentType("image/gif");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 设置验证码参数
        SpecCaptcha specCaptcha = new SpecCaptcha(200, 60, 5);
        // 设置字体
        specCaptcha.setFont(new Font("Verdana", Font.PLAIN, 32));
        // 设置验证码类型
        specCaptcha.setCharType(Captcha.TYPE_DEFAULT);
        // 验证码存入session
        // request.getSession().setAttribute("captcha", specCaptcha.text().toLowerCase());
        // 验证码信息存入redis，10分钟有效
        redisUtil.set(Constants.User.KEY_CAPTCHA_CONTENT + key, specCaptcha.text().toLowerCase(), 10);
        // 输出图片流
        specCaptcha.out(response.getOutputStream());
    }

    /**
     * 发送邮件
     *
     * @param email
     * @reutrn
     */
    @GetMapping("/sendEmail/{email}/{type}")
    public ResponseResult sendEmail(HttpServletRequest request, @PathVariable("email") String email, @PathVariable("type") String type) {
        if (TextUtils.isEmpty(email)) {
            return new ResponseResult(ResponseState.ERROR, "邮箱地址不能为空");
        }
        // 根据类型查找邮箱是否存在
        if ("register".equals(type) || "update".equals(type)) {
            User userByEmail = userService.findOneByEmail(email);
            if (userByEmail != null) {
                return new ResponseResult(ResponseState.ERROR, "该邮箱已注册");
            }
        } else if ("forget".equals(type)) {
            User userByEmail = userService.findOneByEmail(email);
            if (userByEmail == null) {
                return new ResponseResult(ResponseState.ERROR, "该邮箱未注册");
            }
        }
        // 1.防止重复多次发送
        // 同一个邮箱间隔60秒，同一个ip两个小时最多发送10次
        String ip = request.getRemoteAddr();
        // 替换分号
        ip = ip.replaceAll(":", "_");
        Integer ipSendTime = (Integer) redisUtil.get(Constants.User.KEY_EMAIL_SEND_IP + ip);
        if (ipSendTime != null && ipSendTime > 10) {
            return new ResponseResult(ResponseState.ERROR, "你的发送过于频繁，请稍后再试");
        }
        String emailSendTime = (String) redisUtil.get(Constants.User.KEY_EMAIL_SEND_ADDRESS + email);
        if (emailSendTime != null) {
            return new ResponseResult(ResponseState.ERROR, "你的发送过于频繁，请稍后再试");
        }
        // 2.检查邮箱地址是否正确
        if (!TextUtils.isEmailAddress(email)) {
            return new ResponseResult(ResponseState.ERROR, "邮箱地址输入有误");
        }
        // 3.发送邮件
        // 随机验证码:100000~999999
        Integer code = new Random().nextInt(899999) + 100000;
        try {
            // 调用异步邮件发送
            taskService.sendEmailVerifyCode(String.valueOf(code), email);
        } catch (MessagingException e) {
            return new ResponseResult(ResponseState.ERROR, "验证码发送失败");
        }
        // 记录邮箱号，保存1min=60s
        redisUtil.set(Constants.User.KEY_EMAIL_SEND_ADDRESS + email, email, 1);
        // 记录ip，限制2小时十次
        if (ipSendTime == null) {
            ipSendTime = 0;
        }
        ipSendTime++;
        redisUtil.set(Constants.User.KEY_EMAIL_SEND_IP + ip, ipSendTime, 60 * 2);
        // 记录邮箱验证码10min
        redisUtil.set(Constants.User.KEY_EMAIL_CONTENT + email, String.valueOf(code), 10);
        return new ResponseResult(ResponseState.SUCCESS, "验证码发送成功");
    }

    /**
     * 找回密码
     *
     * @param verifyCode
     * @param user
     * @reutrn
     */
    @PutMapping("/password/{verifyCode}")
    public ResponseResult findPassword(@PathVariable("verifyCode") String verifyCode, @RequestBody User user, HttpServletRequest request) {
        return userService.findPassword(verifyCode, user, request);
    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @reutrn
     */
    @GetMapping("/{userId}")
    public ResponseResult getUserInfo(@PathVariable("userId") String userId) {
        return userService.getUserInfo(userId);
    }

    /**
     * 修改用户信息
     *
     * @param userId
     * @param user
     * @reutrn
     */
    @PutMapping("/{userId}")
    public ResponseResult updateUserInfo(HttpServletRequest request, HttpServletResponse response,
                                         @PathVariable("userId") String userId, @RequestBody User user) {
        // 修改
        return userService.updateUserInfo(request, response, userId, user);
    }


    /**
     * 检查邮箱地址
     *
     * @param email
     * @return
     */
    @GetMapping("/email/{email}")
    public ResponseResult checkEmail(@PathVariable("email") String email) {
        return userService.checkEmail(email);
    }

    /**
     * 检查用户名
     *
     * @param userName
     * @return
     */
    @GetMapping("/userName/{userName}")
    public ResponseResult checkUserName(@PathVariable("userName") String userName) {
        return userService.checkUserName(userName);
    }

    /**
     * 修改邮箱
     *
     * @param email
     * @param verifyCode
     * @param request
     * @param response
     * @return
     */
    @PutMapping("/email/{email}/{verifyCode}")
    public ResponseResult updateEmail(@PathVariable("email") String email, @PathVariable("verifyCode") String verifyCode,
                                      HttpServletRequest request, HttpServletResponse response) {
        return userService.updateEmail(email, verifyCode, request, response);
    }

    /**
     * 退出登录
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/logout")
    public ResponseResult doLogout(HttpServletRequest request, HttpServletResponse response) {
        return userService.doLogout(request, response);
    }
}
